]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
background.js: fix updating a BackgroundSource on monitor changes
authorOwen W. Taylor <otaylor@fishsoup.net>
Fri, 12 Sep 2014 21:07:31 +0000 (17:07 -0400)
committerOwen W. Taylor <otaylor@fishsoup.net>
Fri, 12 Sep 2014 21:10:04 +0000 (17:10 -0400)
It was assumed that BackgroundSource objects were always destroyed
on monitor changes because the BackgroundManager objects that hold
references were destroyed, but sequencing of updating of different
BackgroundManager objects meant that was not the case.

Properly update any cached Background objects held by the
BackgroundSource on a change to the monitor layout; in particular this
means updating animations in case they are multi-resolution.

js/ui/background.js

index 00b9d637589ee8495aa19d897088e718efba1c54..9ca9312ec4d83c53470146ed422e4a3b6dd6e180 100644 (file)
@@ -242,11 +242,7 @@ const Background = new Lang.Class({
 
     destroy: function() {
         this._cancellable.cancel();
-
-        if (this._updateAnimationTimeoutId) {
-            GLib.source_remove (this._updateAnimationTimeoutId);
-            this._updateAnimationTimeoutId = 0;
-        }
+        this._removeAnimationTimeout();
 
         let i;
         let keys = Object.keys(this._fileWatches);
@@ -260,6 +256,13 @@ const Background = new Lang.Class({
         this._settingsChangedSignalId = 0;
     },
 
+    updateResolution: function() {
+        if (this._animation) {
+            this._removeAnimationTimeout();
+            this._updateAnimation();
+        }
+    },
+
     _setLoaded: function() {
         if (this.isLoaded)
             return;
@@ -303,6 +306,13 @@ const Background = new Lang.Class({
         this._fileWatches[filename] = signalId;
     },
 
+    _removeAnimationTimeout: function() {
+        if (this._updateAnimationTimeoutId) {
+            GLib.source_remove(this._updateAnimationTimeoutId);
+            this._updateAnimationTimeoutId = 0;
+        }
+    },
+
     _updateAnimation: function() {
         this._updateAnimationTimeoutId = 0;
 
@@ -477,6 +487,23 @@ const BackgroundSource = new Lang.Class({
         this._overrideImage = GLib.getenv('SHELL_BACKGROUND_IMAGE');
         this._settings = new Gio.Settings({ schema_id: settingsSchema });
         this._backgrounds = [];
+
+        this._monitorsChangedId = global.screen.connect('monitors-changed',
+                                                        Lang.bind(this, this._onMonitorsChanged));
+    },
+
+    _onMonitorsChanged: function() {
+        for (let monitorIndex in this._backgrounds) {
+            let background = this._backgrounds[monitorIndex];
+
+            if (monitorIndex < this._layoutManager.monitors.length) {
+                background.updateResolution();
+            } else {
+                background.disconnect(background._changedId);
+                background.destroy();
+                delete this._backgrounds[monitorIndex];
+            }
+        }
     },
 
     getBackground: function(monitorIndex) {
@@ -513,8 +540,8 @@ const BackgroundSource = new Lang.Class({
                 style: style
             });
 
-            let changedId = background.connect('changed', Lang.bind(this, function() {
-                background.disconnect(changedId);
+            background._changedId = background.connect('changed', Lang.bind(this, function() {
+                background.disconnect(background._changedId);
                 background.destroy();
                 delete this._backgrounds[monitorIndex];
             }));
@@ -526,8 +553,13 @@ const BackgroundSource = new Lang.Class({
     },
 
     destroy: function() {
-        for (let monitorIndex in this._backgrounds)
-            this._backgrounds[monitorIndex].destroy();
+        global.screen.disconnect(this._monitorsChangedId);
+
+        for (let monitorIndex in this._backgrounds) {
+            let background = this._backgrounds[monitorIndex];
+            background.disconnect(background._changedId);
+            background.destroy();
+        }
 
         this._backgrounds = null;
     }